import { _decorator, Component, instantiate, Label, Node, Prefab, size, sp, Sprite, SpriteFrame, tween, Tween, UITransform, v3, Vec3 } from 'cc';
import { BaseViewCmpt } from '../../Frame/Script/Base/baseViewCmpt';
import { App } from '../app';
import { Block } from '../item/Block';
import { ResLoadHelper } from '../../Frame/Script/resLoadHelper';
import { NextBlock } from '../item/NextBlock';
import { EventName } from '../../Frame/Script/const/eventName';
import { ToolsHelper } from '../../Frame/Script/toolsHelper';
import { NetInfo } from '../core/NetInfo';
import { MsgClearLine } from '../network/net_proto/protocols/game/MsgClearLine';
import { MsgGameOver } from '../network/net_proto/protocols/game/MsgGameOver';
import { MsgGamePlaying } from '../network/net_proto/protocols/game/MsgGamePlaying';
import { ViewName } from '../../Frame/Script/const/viewNameConst';
import { MsgComeUp } from '../network/net_proto/protocols/game/MsgComeUp';
import { MsgSink } from '../network/net_proto/protocols/game/MsgSink';
import { AudioName } from '../../Frame/Script/const/enumConst';
const { ccclass, property } = _decorator;

const seatX = {
    2: [-260, -260, 260, 260],
    4: [-305, -220, 220, 305]
}
const xialuo_spine_name = ["one", "two", "three", "four"];

@ccclass('Model2ViewManager')
export class Model2ViewManager extends BaseViewCmpt {

    private grid_par: Node = null;
    private grid_model: Node = null;
    private seat1: Node = null;
    private seat2: Node = null;
    private seat3: Node = null;
    private seat4: Node = null;
    private block_box: Node = null;
    private time_label: Label = null;
    private self_block_area: Node = null;
    private other_block_area: Node = null;
    private next_block_area: Node = null;
    private count_down_label: Label = null;
    private img_public_tail: Node = null;
    private at_label: Label = null;
    private blue_at_label: Label = null;
    private red_at_label: Label = null;
    private bottomUI: Node = null;

    private anim_fx_alarm: sp.Skeleton = null;
    private anim_fx_hitframe: sp.Skeleton = null;
    private anim_fx_burst: sp.Skeleton = null;
    private anim_fx_warning: sp.Skeleton = null;
    private anim_fx_line: sp.Skeleton = null;
    private anim_ko: sp.Skeleton = null;
    private anim_fx_blast: sp.Skeleton = null;
    private anim_xialuo: sp.Skeleton = null;
    private anim_xiaochu: sp.Skeleton = null;
    private anim_fx_flash: sp.Skeleton = null;
    private other_anim_xiaochu: sp.Skeleton = null;
    private other_anim_fx_flash: sp.Skeleton = null;
    private anim_gaojixiaochu: sp.Skeleton = null;
    private anim_fx_blockfire: sp.Skeleton = null;
    private other_anim_fx_blockfire: sp.Skeleton = null;

    private self_anim_clear_list: sp.Skeleton[] = [];
    private self_anim_leidian_list: sp.Skeleton[] = [];
    private other_anim_clear_list: sp.Skeleton[] = [];
    private other_anim_leidian_list: sp.Skeleton[] = [];

    private countValue: number = 3;
    private selfMapData: Block[][] = [];
    private otherMapData: Block[][] = [];
    private nextData: NextBlock[][] = [];
    private oldShape1: number[][] = null;
    private oldShape2: number[][] = null;
    private oldShape3: number[][] = null;
    private oldShape4: number[][] = null;

    /** 结束的预警动画 */
    private over_alarm_playing: boolean = false;

    protected onLoad(): void {
        super.onLoad();
        this.grid_par = this.viewList.get("content/gameLeft/gridPar");
        this.grid_model = this.viewList.get("content/gameLeft/gridPar/img_grid");
        this.seat1 = this.viewList.get("content/top/seat1");
        this.seat2 = this.viewList.get("content/top/seat2");
        this.seat3 = this.viewList.get("content/top/seat3");
        this.seat4 = this.viewList.get("content/top/seat4");
        this.self_block_area = this.viewList.get("content/gameLeft/selfBlockArea");
        this.other_block_area = this.viewList.get("content/gameRight/top/otherBlockArea");
        this.next_block_area = this.viewList.get("content/gameRight/bottom/blockShow/nextBlockArea");
        this.block_box = this.viewList.get("content/gameLeft/img_block_box");
        this.time_label = this.viewList.get("content/top/timeLabel").getComponent(Label);
        this.count_down_label = this.viewList.get("content/gameLeft/img_block_box/countDownLabel").getComponent(Label);
        this.img_public_tail = this.viewList.get("content/animaMask/img_public_tail");
        this.at_label = this.viewList.get("content/gameRight/top/atParent/atLabel").getComponent(Label);
        this.blue_at_label = this.viewList.get("content/top/pk/blueAttackLabel").getComponent(Label);
        this.red_at_label = this.viewList.get("content/top/pk/redAttackLabel").getComponent(Label);
        this.bottomUI = this.viewList.get("content/bottom");

        this.anim_fx_alarm = this.viewList.get("content/animaMask/anim_fx_alarm").getComponent(sp.Skeleton);
        this.anim_fx_hitframe = this.viewList.get("content/animaMask/anim_fx_hitframe").getComponent(sp.Skeleton);
        this.anim_fx_burst = this.viewList.get("content/gameRight/top/anim_fx_burst").getComponent(sp.Skeleton);
        this.anim_fx_warning = this.viewList.get("content/gameLeft/anim_fx_warning").getComponent(sp.Skeleton);
        this.anim_fx_line = this.viewList.get("content/animaMask/anim_fx_line").getComponent(sp.Skeleton);
        this.anim_ko = this.viewList.get("content/gameLeft/anim_ko").getComponent(sp.Skeleton);
        this.anim_fx_blast = this.viewList.get("content/gameLeft/anim_fx_blast").getComponent(sp.Skeleton);
        this.anim_xialuo = this.viewList.get("content/gameLeft/anim_xialuo").getComponent(sp.Skeleton);
        this.anim_xiaochu = this.viewList.get("content/gameLeft/anim_xiaochu").getComponent(sp.Skeleton);
        this.anim_fx_flash = this.viewList.get("content/gameLeft/anim_fx_flash").getComponent(sp.Skeleton);
        this.other_anim_xiaochu = this.viewList.get("content/gameRight/top/anim_xiaochu").getComponent(sp.Skeleton);
        this.other_anim_fx_flash = this.viewList.get("content/gameRight/top/anim_fx_flash").getComponent(sp.Skeleton);
        this.anim_gaojixiaochu = this.viewList.get("content/gameLeft/anim_gaojixiaochu").getComponent(sp.Skeleton);
        this.anim_fx_blockfire = this.viewList.get("content/gameLeft/anim_fx_blockfire").getComponent(sp.Skeleton);
        this.other_anim_fx_blockfire = this.viewList.get("content/gameRight/top/anim_fx_blockfire").getComponent(sp.Skeleton);

        App.event.on(EventName.Game.GAME_PLAYING, this.onUpdateViewContent, this);
        App.event.on(EventName.Game.CLEAR_LINE, this.onClearLine, this);
        App.event.on(EventName.Game.SINK, this.onSink, this);
        App.event.on(EventName.Game.COME_UP, this.onComeUp, this);
        App.event.on(EventName.Game.GAME_OVER, this.onGameOver, this);
        //此处改为倒计时时间由服务器传递
        // App.event.on(EventName.Game.TIMER_DOWN, this.onTimeDown, this);
    }

    protected start(): void {
        App.gameData.isGameStart = false;
        App.gameData.isGameOver = false;
        this.bottomUI.active = App.user.seatId !== 0;
        App.gameData.blue_at_count = 0;
        App.gameData.red_at_count = 0;
        this.initViewSize();
        this.initSeatShow();
        this.initGameArea();
        this.initNextArea();

        this.updateAtTotalCount(0, 0);
        this.initSkeletonAnim();
        // 播放倒计时动画
        this.playCountDownAnim();
    }

    private playCountDownAnim() {
        this.time_label.string = ToolsHelper.toMinBySeconds2(App.timer.TimeDownConst);
        this.schedule(() => {
            this.countValue -= 1;
            if (this.countValue === -1) {
                App.audio.playEffect(AudioName.game_end_count_down);
                this.count_down_label.node.active = false;
                App.gameData.isGameStart = true;
            } else {
                App.audio.playEffect(AudioName.game_start_count_down);
                this.count_down_label.string = this.countValue.toString();
            }
        }, 1, 4);
    }

    private onTimeDown(timeValue: number) {
        this.time_label.string = ToolsHelper.toMinBySeconds2(timeValue);
        if (timeValue <= 0) {
            console.log("全局倒计时归零，游戏结束");
        }
    }

    private onUpdateViewContent(data: MsgGamePlaying) {
        // console.log("MsgGamePlaying=>", data);
        let self_seatId = App.user.seatId > 0 ? App.user.seatId : 1;
        let team1_map = data.selfMap, team2_map = data.otherMap;
        this.updateSelfGameArea(self_seatId > 2 ? team2_map : team1_map);
        this.updateOtherGameArea(self_seatId > 2 ? team1_map : team2_map);
        this.updateNextArea(data["nextShape_" + self_seatId], self_seatId);
        this.onTimeDown(data.TimeDown);
        if (data.bornRowCol) {
            console.log("--playing--", data);
            /** 触发落定的座位id，用户判断动画的播放 */
            let trigger_seatId = data.seatId;
            let isAlarm: boolean = false;
            let shape_wid = this["oldShape" + trigger_seatId][0].length;
            let shape_hei = this["oldShape" + trigger_seatId].length;
            if (self_seatId > 2) {
                if (trigger_seatId > 2) {
                    this.controlDropAnim(true, shape_wid, shape_hei, data.bornRowCol);
                } else {
                    console.log("播放右上角小map的下落动画");
                }
                isAlarm = this.checkIsAlarm(team2_map);
            } else {
                if (trigger_seatId > 2) {
                    console.log("播放右上角小map的下落动画");
                } else {
                    this.controlDropAnim(true, shape_wid, shape_hei, data.bornRowCol);
                }
                isAlarm = this.checkIsAlarm(team1_map);
            }
            this.controlAlarmAnim(isAlarm);
        } else {
            this.oldShape1 = data.currentShape_1;
            this.oldShape2 = data.currentShape_2;
            this.oldShape3 = data.currentShape_3;
            this.oldShape4 = data.currentShape_4;
        }
    }

    private onClearLine(data: MsgClearLine) {
        console.log("MsgClearLine=>", data);
        this.updateAtTotalCount(data.team1_at_total, data.team2_at_total);
        let trigger_seatId = data.seatId;
        let self_seatId = App.user.seatId > 0 ? App.user.seatId : 1;
        let clearLine = data.clearLine;
        if (self_seatId > 2) {
            if (trigger_seatId > 2) {
                this.playSelfClearLineAnim(clearLine);
                App.audio.playEffect(AudioName.clear_row);
                // 攻击对方
                if (clearLine.length >= 2) {
                    this.playAtAnim(clearLine, data.team2_at_count);
                    this.controlOtherBlockFireAnim(true);
                }
            } else {
                this.playOtherClearLineAnim(clearLine);
                if (clearLine.length >= 2) {
                    this.controlSelfBlockFireAnim(true);
                }
            }
        } else {
            if (trigger_seatId > 2) {
                this.playOtherClearLineAnim(clearLine);
                if (clearLine.length >= 2) {
                    this.controlSelfBlockFireAnim(true);
                }
            } else {
                this.playSelfClearLineAnim(clearLine);
                App.audio.playEffect(AudioName.clear_row);
                // 攻击对方
                if (clearLine.length >= 2) {
                    this.playAtAnim(clearLine, data.team1_at_count);
                    this.controlOtherBlockFireAnim(true);
                }
            }
        }
    }

    /** 播放攻击动画 */
    private playAtAnim(clearLine: number[], atValue: number) {
        this.controlHitFrameAnim(true);
        clearLine.sort((a, b) => { return a - b });
        let idx = Math.ceil(clearLine.length / 2) - 1;
        let rowValue = clearLine[idx];
        let offset_y = (10.5 - rowValue + 1) * App.gameData.GridSize;
        let startV = v3(-100, offset_y, 0);
        let targetV = v3(260, 286, 0);
        let v = targetV.clone().subtract(startV);
        let angle = -Vec3.angle(v, v3(1, 0, 0)) * 180 / Math.PI;
        Tween.stopAllByTarget(this.img_public_tail);
        this.img_public_tail.setPosition(startV);
        this.img_public_tail.angle = angle;
        tween(this.img_public_tail)
            .to(0.1, { position: targetV })
            .call(() => {
                this.controlHitLabelAnim(true, atValue);
                this.controlLineAnim(true);
                this.controlBurstAnim(true);
            })
            .start()

    }

    /** 检查是否需要播放警告动画 */
    private checkIsAlarm(map: number[][]): boolean {
        let result: boolean = false;
        const checkRow: number = 5;
        for (let j = 0; j < map[checkRow].length; j++) {
            let value = map[checkRow][j];
            if (value % 10 === 1) {
                result = true;
                break;
            }
        }
        return result;
    }

    /** 播放左边的消除动画 */
    private playSelfClearLineAnim(clearLine: number[]) {
        this.controlSelfClearAnim(true, clearLine);
        this.controlGaojiAnim(true);
    }

    /** 播放右边的消除动画 */
    private playOtherClearLineAnim(clearLine: number[]) {
        this.controlOtherClearAnim(true, clearLine);
    }

    private onComeUp(data: MsgComeUp) {
        console.log("MsgComeUp=>", data);
        let seatId = App.user.seatId > 0 ? App.user.seatId : 1;
        if (seatId > 2) {
            this.updateSelfGameArea(data.otherMap);
            this.updateOtherGameArea(data.selfMap);
        } else {
            this.updateSelfGameArea(data.selfMap);
            this.updateOtherGameArea(data.otherMap);
        }
    }

    private onSink(data: MsgSink) {
        console.log("MsgSink=>", data);
        let seatId = App.user.seatId > 0 ? App.user.seatId : 1;
        if (seatId > 2) {
            this.updateSelfGameArea(data.otherMap);
            this.updateOtherGameArea(data.selfMap);
        } else {
            this.updateSelfGameArea(data.selfMap);
            this.updateOtherGameArea(data.otherMap);
        }
    }

    private onGameOver(data: MsgGameOver) {
        console.log("MsgGameOver=>", data);
        App.audio.playEffect(AudioName.game_over);
        App.gameData.isGameOver = data.isOver;
        //设置局势标签 0平局 1胜利 2失败
        let type: number = 0;
        if (App.gameData.blue_at_count === App.gameData.red_at_count) {
            type = 0;
            this.controlKOAnim(true, false);
        } else {
            let seatId = App.user.seatId > 0 ? App.user.seatId : 1;
            if (seatId > 2) {
                type = (data.team2_isWon && !data.team1_isWon) ? 1 : 2;
            } else {
                type = (data.team1_isWon && !data.team2_isWon) ? 1 : 2;
            }
            let self_isWon = type === 1 ? true : false;
            this.controlKOAnim(true, self_isWon);
        }
        App.gameData.setSettleType(type);
        let seats = App.gameData.getGameSeats();
        for (let i = 0; i < seats.length; i++) {
            let seat_data = seats[i];
            if (seat_data.user) {
                seat_data.user.isReady = false;
            }
        }
        if (data.isOver) {
            this.controlAlarmAnim(false);
            this.scheduleOnce(() => {
                this.onClick_closeBtn();
                App.view.openView(ViewName.Single.eModel2OverView);
            }, 3)
        }
    }

    /** 更新红蓝双方的攻击次数 */
    private updateAtTotalCount(blueCount: number, redCount: number) {
        App.gameData.blue_at_count = blueCount;
        App.gameData.red_at_count = redCount;
        this.blue_at_label.string = '' + blueCount;
        this.red_at_label.string = '' + redCount;
    }

    private async initGameArea() {
        let gridSize = App.gameData.GridSize;
        let tabular: number[] = App.gameData.VERSUS;
        const [total_row, total_col] = tabular;
        let block_pre = await ResLoadHelper.loadAssetSync("prefabs/item/block", Prefab) as Prefab;
        let self_block: Node = null;
        let self_blockCom: Block = null;
        for (let row = 0, y = -gridSize; row < total_row; row++, y -= gridSize) {
            this.selfMapData[row] = [];
            for (let col = 0, x = 0; col < total_col; col++, x += gridSize) {
                self_block = instantiate(block_pre);
                self_block.getComponent(UITransform).setContentSize(size(36, 36));
                self_block.setPosition(v3(x, y, 0));
                self_blockCom = self_block.getComponent(Block);
                self_blockCom.initBlock(false);
                self_block.parent = this.self_block_area;
                this.selfMapData[row][col] = self_blockCom;
            }
        }

        const otherGridSize = 16;
        let other_block: Node = null;
        let other_blockCom: Block = null;
        for (let row = 0, y = -otherGridSize; row < total_row; row++, y -= otherGridSize) {
            this.otherMapData[row] = [];
            for (let col = 0, x = 0; col < total_col; col++, x += otherGridSize) {
                other_block = instantiate(block_pre);
                other_block.getComponent(UITransform).setContentSize(size(otherGridSize, otherGridSize));
                other_block.setPosition(v3(x, y - 10, 0));
                other_blockCom = other_block.getComponent(Block);
                other_blockCom.initBlock(false);
                other_block.parent = this.other_block_area;
                this.otherMapData[row][col] = other_blockCom;
            }
        }
    }

    private async initNextArea() {
        let offset = 16;
        let next_block_pre = await ResLoadHelper.loadAssetSync("prefabs/item/nextBlock", Prefab) as Prefab;
        let next_block: Node = null;
        let next_blockCom: NextBlock = null;
        for (let row = 0, y = 0; row < 4; row++, y -= 21) {
            this.nextData[row] = [];
            for (let col = 0, x = 0; col < 4; col++, x += 21) {
                next_block = instantiate(next_block_pre);
                next_block.getComponent(UITransform).setContentSize(size(20, 20));
                next_block.setPosition(v3(x + offset, y - offset, 0));
                next_blockCom = next_block.getComponent(NextBlock);
                next_blockCom.initBlock(false);
                next_block.parent = this.next_block_area;
                this.nextData[row][col] = next_blockCom;
            }
        }
    }

    private updateSelfGameArea(map: number[][]) {
        let value = 0;
        let color_value = 1;
        let blockCom: Block = null;
        for (let i = 0; i < this.selfMapData.length; i++) {
            for (let j = 0; j < this.selfMapData[0].length; j++) {
                if (!map[i + 3]) return;
                value = map[i + 3][j];
                color_value = (value / 10) | 0;
                blockCom = this.selfMapData[i][j];
                blockCom.setBlock(color_value, value > 0);
            }
        }
    }

    private updateOtherGameArea(map: number[][]) {
        let value = 0;
        let color_value = 1;
        let blockCom: Block = null;
        for (let i = 0; i < this.otherMapData.length; i++) {
            for (let j = 0; j < this.otherMapData[0].length; j++) {
                if (!map[i + 3]) return;
                value = map[i + 3][j];
                color_value = (value / 10) | 0;
                blockCom = this.otherMapData[i][j];
                blockCom.setBlock(color_value, value > 0);
            }
        }
    }

    private updateNextArea(shape: number[][], seatId: number) {
        let value = 0;
        for (let i = 0; i < this.nextData.length; i++) {
            for (let j = 0; j < this.nextData[i].length; j++) {
                let nextBlock = this.nextData[i][j];
                if (shape[i] && shape[i][j] && shape[i][j] > 0) {
                    value = shape[i][j];
                } else {
                    value = 0;
                }
                nextBlock.setBlock(seatId, value > 0);
            }
        }
    }

    private initViewSize() {
        let game_size: number[] = App.gameData.VERSUS;
        let grid_total = game_size[0] * game_size[1];
        for (let i = 0; i < grid_total; i++) {
            if (i === 0) {
                this.grid_model.name = "grid_" + i;
            } else {
                let grid = instantiate(this.grid_model);
                grid.name = "grid_" + i;
                grid.parent = this.grid_par;
            }
        }
    }

    private initSeatShow() {
        let seats = App.gameData.getGameSeats();
        let people_num = App.gameData.getPeopleNum();
        let posXList: number[] = ToolsHelper.cloneObject(seatX[people_num]);
        for (let i = 0; i < 4; i++) {
            let seat_data = seats[i];
            let seatId = i + 1;
            let p: Node = this["seat" + seatId];
            let posX = posXList[i];
            p.setPosition(v3(posX, 10, 0));
            let nameLabel = p.getChildByName("nameLabel").getComponent(Label);
            let head_spr = p.getChildByName("mask").children[0].getComponent(Sprite);
            let head_default = p.getChildByName("img_default_head");
            if (seat_data.user) {
                p.active = true;
                nameLabel.string = seat_data.user.name;
                head_default.active = false;
                head_spr.node.active = true;
                ResLoadHelper.loadAssetAsync(seat_data.user.icon, SpriteFrame, (frame: SpriteFrame) => {
                    if (frame) {
                        head_spr.spriteFrame = frame;
                    } else {
                        head_default.active = true;
                        head_spr.node.active = false;
                    }
                }, true)
            } else {
                p.active = false;
                nameLabel.string = "";
            }
        }
    }

    /** 初始化spine动画 */
    private async initSkeletonAnim() {
        /** 检查原版没有显示这个动画，暂不展示 */
        // this.controlWarningAnim(false);
        this.controlKOAnim(false);
        this.controlAlarmAnim(false);
        this.controlDropAnim(false);
        this.controlHitFrameAnim(false);
        this.controlLineAnim(false);
        this.controlBurstAnim(false);
        this.controlHitLabelAnim(false);
        this.controlSelfBlockFireAnim(false);
        this.controlOtherBlockFireAnim(false);
        await this.initClearAnimList();
        this.controlSelfClearAnim(false);
        this.controlOtherClearAnim(false);
        this.controlGaojiAnim(false);
    }

    /** 控制左边被攻击时底部的火焰动画 */
    private controlSelfBlockFireAnim(isPlay: boolean) {
        if (isPlay) {
            this.anim_fx_blockfire.node.active = true;
            this.anim_fx_blockfire.setAnimation(0, "2v2_fire", false);
        } else {
            this.anim_fx_blockfire.node.active = false;
        }
    }

    /** 控制右边被攻击时底部的火焰动画 */
    private controlOtherBlockFireAnim(isPlay: boolean) {
        if (isPlay) {
            this.other_anim_fx_blockfire.node.active = true;
            this.other_anim_fx_blockfire.setAnimation(0, "2v2_fire", false);
        } else {
            this.other_anim_fx_blockfire.node.active = false;
        }
    }

    /** 控制全屏幕电的动画 */
    private controlHitFrameAnim(isPlay: boolean) {
        if (isPlay) {
            this.anim_fx_hitframe.node.active = true;
            this.anim_fx_hitframe.setAnimation(0, "frame", false);
        } else {
            this.anim_fx_hitframe.node.active = false;
        }
    }

    /** 控制攻击光线的动画 */
    private controlLineAnim(isPlay: boolean) {
        if (isPlay) {
            this.anim_fx_line.node.active = true;
            this.anim_fx_line.setAnimation(0, "path12", false);
        } else {
            this.anim_fx_line.node.active = false;
        }
    }

    /** 控制右边地图的爆炸效果动画 */
    private controlBurstAnim(isPlay: boolean) {
        if (isPlay) {
            this.anim_fx_burst.node.active = true;
            this.anim_fx_burst.setAnimation(0, "animation", false)
        } else {
            this.anim_fx_burst.node.active = false;
        }
    }

    /** 控制右边地图的被攻击的文本动画 */
    private controlHitLabelAnim(isPlay: boolean, atValue?: number) {
        if (isPlay) {
            this.at_label.string = atValue.toString();
            Tween.stopAllByTarget(this.at_label.node.parent);
            this.at_label.node.parent.setPosition(v3(0, 0, 0));
            this.at_label.node.parent.active = true;
            tween(this.at_label.node.parent)
                .show()
                .by(0.1, { position: v3(0, 50, 0) })
                .delay(0.1)
                .hide()
                .start();
        } else {
            this.at_label.node.parent.setPosition(v3(0, 0, 0));
            this.at_label.node.parent.active = false;
        }
    }

    /** 控制结束的底层警告动画 */
    private controlWarningAnim(isPlay: boolean) {
        if (isPlay) {
            this.anim_fx_warning.node.active = true;
            this.anim_fx_warning.setAnimation(0, "2v2", true);
        } else {
            this.anim_fx_warning.node.active = false;
        }
    }

    /** 控制结束的全屏预警红色闪烁动画 */
    private controlAlarmAnim(isPlay: boolean) {
        if (isPlay) {
            if (this.over_alarm_playing) return;
            this.over_alarm_playing = true;
            this.anim_fx_alarm.node.active = true;
            this.anim_fx_alarm.setAnimation(0, "animation", true);
        } else {
            this.over_alarm_playing = false;
            this.anim_fx_alarm.node.active = false;
            this.anim_fx_alarm.clearTracks();
        }
    }

    /** 控制快速落定动画效果 */
    private controlDropAnim(isPlay: boolean, widCount?: number, heiCount?: number, bornRowCol?: number[]) {
        if (isPlay) {
            if (widCount !== undefined) {
                let idx = widCount - 1;
                let spine_name = xialuo_spine_name[idx];
                let ranType = (Math.random() * 3 + 1) | 0;
                let blast_name = "blast0" + ranType;
                let people_num = App.gameData.getPeopleNum();
                let game_size: number[] = App.gameData["TEAMWORk_" + people_num];
                let middle_col = game_size[1] / 2;
                let offset_x = (bornRowCol[1] + widCount / 2 - middle_col) * App.gameData.GridSize;
                let offset_y = (10.5 - bornRowCol[0] - heiCount / 2) * App.gameData.GridSize;
                this.anim_xialuo.node.setPosition(v3(offset_x, offset_y, 0));
                this.anim_fx_blast.node.setPosition(v3(offset_x, offset_y, 0));
                this.anim_xialuo.node.active = offset_y < this.block_box.getComponent(UITransform).height / 2;
                this.anim_fx_blast.node.active = offset_y < this.block_box.getComponent(UITransform).height / 2;
                this.anim_xialuo.setAnimation(0, spine_name, false);
                this.anim_fx_blast.setAnimation(0, blast_name, false);
            }
        } else {
            this.anim_xialuo.node.active = false;
            this.anim_fx_blast.node.active = false;
        }
    }

    /** 消除动画最多可以是四个，最少一个，所以直接创建四个出来，进行动态控制 */
    private initClearAnimList() {
        for (let i = 0; i < 4; i++) {
            let newSelfClearNode = instantiate(this.anim_xiaochu.node);
            newSelfClearNode.parent = this.anim_xiaochu.node.parent;
            newSelfClearNode.active = false;
            let newClearSpine = newSelfClearNode.getComponent(sp.Skeleton);
            newClearSpine.premultipliedAlpha = false;
            this.self_anim_clear_list.push(newClearSpine);

            let newOtherClearNode = instantiate(this.other_anim_xiaochu.node);
            newOtherClearNode.parent = this.other_anim_xiaochu.node.parent;
            newOtherClearNode.active = false;
            let newOtherClearSpine = newOtherClearNode.getComponent(sp.Skeleton);
            newOtherClearSpine.premultipliedAlpha = false;
            this.other_anim_clear_list.push(newOtherClearSpine);

            let newSelfLeidianNode = instantiate(this.anim_fx_flash.node);
            newSelfLeidianNode.parent = this.anim_fx_flash.node.parent;
            newSelfLeidianNode.active = false;
            let newLeidianSpine = newSelfLeidianNode.getComponent(sp.Skeleton);
            newLeidianSpine.premultipliedAlpha = false;
            this.self_anim_leidian_list.push(newLeidianSpine);

            let newOtherLeidianNode = instantiate(this.other_anim_fx_flash.node);
            newOtherLeidianNode.parent = this.other_anim_fx_flash.node.parent;
            newOtherLeidianNode.active = false;
            let newOtherLeidianSpine = newOtherLeidianNode.getComponent(sp.Skeleton);
            newOtherLeidianSpine.premultipliedAlpha = false;
            this.other_anim_leidian_list.push(newOtherLeidianSpine);
        }
    }

    /** 左边消除动画控制逻辑 */
    private controlSelfClearAnim(isPlay: boolean, clearLine?: number[]) {
        this.anim_xiaochu.node.active = false;
        this.anim_fx_flash.node.active = false;
        this.self_anim_clear_list.forEach(e => e.node.active = false);
        this.self_anim_leidian_list.forEach(e => e.node.active = false);
        if (isPlay) {
            clearLine.forEach((rowValue, index) => {
                let clearSpine = this.self_anim_clear_list[index];
                let leidianSpine = this.self_anim_leidian_list[index];
                let offset_y = (10.5 - rowValue + 1) * App.gameData.GridSize;
                clearSpine.node.setPosition(v3(0, offset_y, 0));
                leidianSpine.node.setPosition(v3(0, offset_y, 0));
                clearSpine.node.active = true;
                leidianSpine.node.active = true;
                clearSpine.setAnimation(0, "2v2", false);
                leidianSpine.setAnimation(0, "2v2_line1", false);
            })
        }
    }

    /** 右边消除动画控制逻辑 */
    private controlOtherClearAnim(isPlay: boolean, clearLine?: number[]) {
        this.other_anim_xiaochu.node.active = false;
        this.other_anim_fx_flash.node.active = false;
        this.other_anim_clear_list.forEach(e => e.node.active = false);
        this.other_anim_leidian_list.forEach(e => e.node.active = false);
        if (isPlay) {
            clearLine.forEach((rowValue, index) => {
                let clearSpine = this.other_anim_clear_list[index];
                let leidianSpine = this.other_anim_leidian_list[index];
                let offset_y = (10.5 - rowValue + 1) * 16;
                clearSpine.node.setPosition(v3(0, offset_y, 0));
                leidianSpine.node.setPosition(v3(0, offset_y, 0));
                clearSpine.node.active = true;
                leidianSpine.node.active = true;
                clearSpine.setAnimation(0, "2v2", false);
                leidianSpine.setAnimation(0, "2v2_line1", false);
            })
        }
    }

    /** 消除同时的边框动画 */
    private controlGaojiAnim(isPlay: boolean) {
        if (isPlay) {
            this.anim_gaojixiaochu.node.active = true;
            this.anim_gaojixiaochu.setAnimation(0, "2v2", false);
        } else {
            this.anim_gaojixiaochu.node.active = false;
        }
    }

    /** 游戏结束动画 */
    private controlKOAnim(isPlay: boolean, isWon?: boolean) {
        if (isPlay) {
            this.anim_ko.node.active = true;
            let anim_name = isWon ? "anim_ko" : "anim_gameover";
            this.anim_ko.setAnimation(0, anim_name, false);
        } else {
            this.anim_ko.node.active = false;
        }
    }

    protected onDestroy(): void {
        App.event.off(EventName.Game.GAME_PLAYING, this);
        App.event.off(EventName.Game.CLEAR_LINE, this);
        App.event.off(EventName.Game.SINK, this);
        App.event.off(EventName.Game.GAME_OVER, this);
        // App.event.off(EventName.Game.TIMER_DOWN, this);
    }
}


